/*****************************************************************************
 *                                                                           *
 * Module:       SRAM_Controller                                             *
 * Description:                                                              *
 *      This module is used for the sram controller for part II of the bus   *
 *   communication exercise in Altera's computer organization lab set.       *
 *                                                                           *
 * This module is a skeleton and must be completed as part of this exercise. *
 *                                                                           *
 *****************************************************************************/

module SRAM_Controller (
	// Inputs
	clk,
	reset_n,
	
	address,
	bus_enable,
	byte_enable,
	rw,
	write_data,
	
	// Bidirectionals
	SRAM_DQ,
	
	// Outputs
	acknowledge,
	read_data,
	
	SRAM_ADDR,

	SRAM_CE_N,
	SRAM_WE_N,
	SRAM_OE_N,
	SRAM_UB_N,
	SRAM_LB_N
);

/*****************************************************************************
 *                           Parameter Declarations                          *
 *****************************************************************************/


/*****************************************************************************
 *                             Port Declarations                             *
 *****************************************************************************/

// Inputs
input				clk;
input				reset_n;

input		[18:0]	address;
input				bus_enable;
input		[1:0]	byte_enable;
input				rw;
input		[15:0]	write_data;

// Bidirectionals
inout		[15:0]	SRAM_DQ;

// Outputs
output				acknowledge;
output		[15:0]	read_data;

output		[17:0]	SRAM_ADDR;

output				SRAM_CE_N;
output				SRAM_WE_N;
output				SRAM_OE_N;
output				SRAM_UB_N;
output				SRAM_LB_N;


/*****************************************************************************
 *                 Internal Wires and Registers Declarations                 *
 *****************************************************************************/

// Internal Wires

// Internal Registers

// State Machine Registers

	reg [1:0] current, next;
	parameter [1:0] A=0, B=1, C=2, D=3;
	
/*****************************************************************************
 *                         Finite State Machine(s)                           *
 *****************************************************************************/
	always @(current) begin
		case(current)
		A: 
		begin
		if(bus_enable)
			if(rw)
			begin
			//read
				next=C;
			end
			else
			begin
			//write
				next=B;

			end
		else
			next=A;
		end
		
		B: next=D;
		
		C: next=D;
		
		D: next=A;

		default: next=A;
		endcase
	end

/*****************************************************************************
 *                             Sequential Logic                              *
 *****************************************************************************/


/*****************************************************************************
 *                            Combinational Logic                            *
 *****************************************************************************/

assign acknowledge	= (current==D);

assign read_data	= rw? SRAM_DQ:16'hx;//read

assign SRAM_DQ		= rw? 16'hz:write_data;//write

assign SRAM_ADDR	= address[17:0];

assign SRAM_CE_N	= (current==B)|(current==C);
assign SRAM_WE_N	= !rw;
assign SRAM_OE_N	= rw;
assign SRAM_UB_N	= /* Add/Edit code here */ 1'b1;
assign SRAM_LB_N	= /* Add/Edit code here */ 1'b1;

/*****************************************************************************
 *                              Internal Modules                             *
 *****************************************************************************/
always @(posedge clk)
begin
	current <= next;
end

endmodule

